#pragma once

#include "../Headers/authr.h"
#include "../Headers/types.h"
#include "../Headers/log.h"

#include "ws.request.h"

#include <string>

namespace TOB {
  namespace WS {
    
    class Data {
    private:
      int8* _buffer;
      int32 _length;
      std::string* _data;
    public:
      /**
       * Определение ссылки на буфер и длины
       */
      Data(int8* buffer, int32 length);
      Data(std::string buffer);
      /**
       * Создание пустого объекта
       */
      Data();
      /**
       * Удаление объекта и отчистка памяти
       */
      ~Data();
      /**
       * Получить ссылку на буффер данных
       * @return указатель на буффер
       */
      int8* getBuffer();
      /**
       * Получить длину буффера
       * @return длина буффера
       */
      int32& getLength();
      /**
       * Получить строку
       * @return строка
       */
      std::string& getData();
      /**
       * Обратиться к ячейке буфера
       * @param index номер ячейки буфера
       * @return ссылка на ячейку
       */
      int8 operator [](int32 index);
      /**
       * Перегрузка оператора присваивания
       * @param right объект к которому присваивается текущий
       * @return переприсвоенный буфер
       */
      Data& operator =(const Data& right);
    };
    
    class ClientException {
    private:
      Code::Type errorCode;
      std::string message;
    public:
      /**
       * Обработка ошибок
       * @param message сообщение ошибки
       * @param errorCode номер ошибки
       */
      ClientException(std::string message, Code::Type errorCode);
      Code::Type getErrorCode();
      std::string getMessage();
      void writeErrorToLog();
    };
    
    class Client : public AuthRequired {
    public:
      Client(TOB::Nameserver::IP nsip, std::string username, std::string password);
      ~Client();
      /**
       * Получить страницу по запросу
       *
       * @param data ссылка на объект данных
       * @param request запрос (getfile|sendfile|getpage)://имя_сервера/адрес_страницы[?параметр1=[значение1][&...]]
       * @param authr параметр авторизованного запроса
       * @return код возврата из Headers/types.h
       */
      Code::Type request(std::string request, Data& data);
    };
  }
}
